import XLSX from 'xlsx';
import XLSXJS from '@/utils/xlsx.bundle.js';
import { saveAs } from 'file-saver';
import { Loading } from 'element-ui';
export default {
  components: {},
  data() {
    return {
      Loading: null
    };
  },
  methods: {
    //通用加载数据--------------------------------------------------
    loadingData(file) {
      return new Promise((resolve, reject) => {
        this.Loading = Loading.service({ fullscreen: true, text: '加载中...' });
        const content = file.raw;
        if (content) {
          const reader = new FileReader();
          reader.onload = e => {
            const data = new Uint8Array(e.target.result);
            const workbook = XLSX.read(data, { type: 'array' });
            const firstSheetName = workbook.SheetNames[0];
            const worksheet = workbook.Sheets[firstSheetName];
            let excelData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
            excelData = excelData.filter(el => el.length > 0);
            const uniqueArray = [...new Set(excelData)];
            this.Loading.close();
            resolve(uniqueArray);
          };
          reader.readAsArrayBuffer(content);
        }
      });
    },
    //加载时获取规格数据--------------------------------------------
    async getDbSpecificationData() {
      this.dbSpecificationList = [];
      let res = await this.$api.get(this.$url.productSpecificationPageList, { pageSize: 200000, pageNum: 1, commonTag: 1 });
      res.rows.forEach(item => {
        this.dbSpecificationList.push(item.productSpecificationName);
      });
    },
    //下载模板----------------------------------------------------
    downloadFile() {
      const link = document.createElement('a');
      link.href = '/static/files/商品导入模板.xlsx'; // 直接放在 public 根目录下
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    },
    //检查文件----------------------------------------------------
    async checkFile(file) {
      let excelData = await this.loadingData(file);
      let errorFlag = false;
      let msg = '';
      for (let i = 1; i < excelData.length && !errorFlag; i++) {
        for (let j = 0; j < 5; j++) {
          if (!excelData[i][j]) {
            msg = `${i + 1}行${j}列无数据`;
            errorFlag = true;
            break;
          }
        }
      }
      if (excelData[0][0] !== '品牌' && excelData[0][1] !== '货号' && excelData[0][2] !== '商品名称' && excelData[0][3] !== '规格' && excelData[0][4] !== '商品和服务税收编码') {
        this.$message.error('第一行的title不对');
      } else if (errorFlag) {
        this.$message.error(msg);
      } else {
        this.$message.success('数据全部正确');
      }
    },
    //筛选某商品下所有所有数据，筛选出去重后的数据---------------------
    async uniqueData(file) {
      let excelData = await this.loadingData(file);
      let res = await this.$api.get(this.$url.getAllProductByBrand, { productBrandName: excelData[1][0] });
      console.log(res.data)
      let dbData = this.removeNullProperties(res.data);
      let data = this.optimizeFilter(excelData, dbData);
      if (data.length > 0) {
        this.exportList(data, excelData[1][0]);
      } else {
        this.$message.warning('所有数据在数据库中都有，没有新数据');
      }
    },
    //删除数组中的null
    removeNullProperties(arr) {
      const len = arr.length;
      const result = new Array(len); // 预分配结果数组（避免动态扩容）
      for (let i = 0; i < len; i++) {
        const obj = arr[i];
        const newObj = {};
        const keys = Object.keys(obj); // 获取对象自身可枚举属性（比`for...in`快）
        const keyLen = keys.length;
        for (let j = 0; j < keyLen; j++) {
          const key = keys[j];
          const value = obj[key];
          if (value !== null) {
            // 严格保留非`null`值（0、false、''等有效）
            newObj[key] = value;
          }
        }
        result[i] = newObj; // 将新对象存入结果数组
      }
      return result;
    },
    //过滤字符串
    filterStr(str) {
      // eslint-disable-next-line
      return str.trim();
    },
    //过滤掉跟服务器中一样的数据
    optimizeFilter(arrayA, arrayB) {
      // 创建排除集合：将数组B的对象转为字符串键存储
      const excludeSet = new Set();
      for (let i = 0; i < arrayB.length; i++) {
        let obj = arrayB[i];
        // 使用特殊分隔符连接属性值
        excludeSet.add(`${this.filterStr(obj.productBrandArticleNo)}ナ${this.filterStr(obj.productBrandArticleNoName)}ナ${this.filterStr(obj.productSpecificationName)}`);
      }
      // 结果集合：用于去重和结果存储
      const resultSet = new Set();
      const result = [];
      for (const item of arrayA) {
        // 生成标准化键（使用相同分隔符格式）
        const key = `${this.filterStr(item[1])}ナ${this.filterStr(item[2])}ナ${this.filterStr(item[3])}`;
        // 检查是否在排除集或结果集中
        if (!excludeSet.has(key) && !resultSet.has(key)) {
          resultSet.add(key);
          result.push(item); // 保留原始数组引用
        }
      }
      return result;
    },
    //导出文件
    exportList(arr, brandName) {
      arr.reverse();
      let wpx = [{ wpx: 120 }, { wpx: 200 }, { wpx: 500 }, { wpx: 100 }, { wpx: 200 }];
      // arr.push(['品牌', '货号', '商品名称', '规格', '商品和服务税收编码']);
      arr.reverse();
      let worksheet = XLSXJS.utils.json_to_sheet(arr, { skipHeader: true });
      for (const key in worksheet) {
        if (worksheet[key] instanceof Object) {
          worksheet[key].s = {
            alignment: { vertical: 'center', horizontal: 'center', indent: 0, wrapText: true },
            font: { name: '宋体', sz: 10, color: { rgb: '#FF000000' }, bold: false, italic: false, underline: false }
          };
        }
      }
      worksheet['!cols'] = wpx;
      const workbook = XLSXJS.utils.book_new();
      XLSXJS.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); // sheet1 是自定义的sheet名
      // XLSXJS.write 会根据type返回值，为什么选择binary类型，因为binary好歹是个string，H5+的io写入api只支持写入string类型的
      let binaryData = XLSXJS.write(workbook, { bookType: 'xlsx', bookSST: false, type: 'binary' });
      const buf = new ArrayBuffer(binaryData.length);
      const view = new Uint8Array(buf);
      for (let i = 0; i !== binaryData.length; ++i) {
        view[i] = binaryData.charCodeAt(i) & 0xff;
      }
      const d = new Date();
      let startTime = `${d.getFullYear()}年${d.getMonth() + 1}月${d.getDate()}日${d.getHours()}时${d.getMinutes()}分${d.getSeconds()}秒`;
      let fileName = `${brandName}品牌去重后的产品${startTime}.xlsx`;
      let blobData = new Blob([buf], { type: 'application/octer-stream' });
      saveAs(blobData, fileName);
    },
    // // 使用示例
    // const result = filterArrayB(largeArrayA, arrayB);
    //上传文件前预处理---------------------------------------------
    async uploadGoodsData(file) {
      let excelData = await this.loadingData(file);
      excelData.shift();
      this.handleSpecification(excelData);
      this.uploadFile(file);
    },
    //规格去重
    handleSpecification(excelData) {
      let sData = [];
      excelData.forEach(el => {
        sData.push(el[3]);
      });
      const uniqueArray = [...new Set(sData)]; //excel中去重后的数据
      const setA = new Set(this.dbSpecificationList);
      const result = uniqueArray.filter(item => !setA.has(item)); //跟数据库中对比后去重后的数据
      if (result.length > 0) {
        this.$api.post(this.$url.batchAddSpecification, result);
      }
    },
    //上传文件
    async uploadFile(file) {
      const form = new FormData();
      form.append('file', file.raw);
      let res = await this.$api.postFile(this.$url.uploadGoodsInfo, form);
      if (res) {
        this.updataDataBtn();
      } else {
        this.$message.error('上传失败');
      }
    },
    //整理数据--------------------------------------------------
    async updataDataBtn() {
      await this.$api.post(this.$url.updataBrandData, {});
      this.getStatisticsInfo();
      this.getDataList();
      this.$message.success('数据更新成功');
    }
  }
};
